project_folder = "/Volumes/GoogleDrive/My Drive/Melbourne/UNIMELB/Research/Complexity Project/ICx3_new/Code/behavAnalysis/ICx3_supp/"
code_folder = paste0(project_folder, "Code/")
data_folder = paste0(project_folder, "Data/")

setwd(code_folder)
knitr::opts_knit$set(root.dir = code_folder)

#Import functions
source(file.path(code_folder,"DescriptiveFunctions.R"))

# Participant Data
folderModels = "/Volumes/GoogleDrive/My Drive/Melbourne/UNIMELB/Research/Complexity Project/ICx3_new/Code/behavAnalysis/Output/"

folderOut_figures = paste0(project_folder,"Output/Figures")
folderOut_tables = paste0(project_folder,"Output/Tables")
## Setting up the basics
library(ggplot2)
library(knitr)
library(dplyr)
library(ggsignif)
library(pander)
library(plotly)
library(reshape2)
library(Hmisc)
library(readr)
library(brms)
library(parallel)
library(sjstats)
library(bayesplot)
library(bmlm)
library(DiagrammeR)
library(tidyr)

#From easystats:
library(parameters)
library(see)
library(bayestestR)
library(performance)
library(forcats)
library(ggpol)
# brms Input

chains_brms = 4
cores_brms = min(chains_brms,detectCores())
seed_brms = 111
iters_high = 4000
# Functions
save_summarise_model = function(model, modelName){
  if (modelName %in% names(allModels)){
    warning("Model Name already exists!")
    model = allModels[[modelName]]
  } else {
    allModels[[modelName]]<<- model
  }
 
    table = model_parameters(model, 
                              ci_method = "HDI",ci=0.95,test = c("hdi","pd"))
    
    table2 = performance::model_performance(model,metrics="common")

    plo = plot(hdi(model, ci = c(0.95)), data = model)+
          ggtitle("Posterior distributions",
                  "with medians and 95% quantile-based-intervals") +
          theme(plot.title = element_text(hjust = 0.5),
                plot.subtitle = element_text(hjust = 0.5))
  
    print(as_tibble(table))
    print(as_tibble(table2))
    print(plo)
    
    allModels[[modelName]]<<- model
}
# Use current models or rerun everything Comment one option

# allModels := list of all the regressions that are run 


## Option1: Use current saved models

# Import estimated models
allModels = read_rds(file.path(folderModels,"ICx3_models_KS.RData"))

# Don't run brms models
brm2 =  function(...){
  return(FALSE)
}

# ## Option2: Rerun everything from scratch
# 
# allModels=vector("list", length=0)
# 
# brm2 =  function(...){
#   return(brm(...))
# }

1 Knapsack decision problem (KP)

2 Accuracy

Read Clean Data to file


dataTrial_KS= read_csv(file.path(data_folder,"KSDec_clean.csv"),
                       col_types = cols(w = col_character(),
                                        v = col_character()))


dataTrial_KS$region = case_when(
  dataTrial_KS$type %in% c(1,2,3,4) ~ "Phase Transition",
  dataTrial_KS$type %in% c(6) ~ "Underconstrained",
  dataTrial_KS$type %in% c(5) ~ "Overconstrained"
)

2.1 Satisfiability

dataInput=dataTrial_KS

logitRandomIntercept = brm2(correct ~ sol + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0,
                           save_all_pars = TRUE)

tableName='ks_acc_sat1'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

2.2 Number of witnesses

2.2.1 With TCC

dataInput=dataTrial_KS

dataInput = dataInput %>% filter(sol==1)

dataInput$nSolutions_log =log(dataInput$nSolutions)
logitRandomIntercept = brm2(correct ~ nSolutions + phaseT + phaseT:nSolutions + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0,
                           save_all_pars = TRUE)

tableName='ks_acc_ns1'
save_summarise_model(allModels[['ks_acc_ns1']], tableName)
Model Name already exists!

model = allModels[['ks_acc_ns1']]
plot(marginal_effects(model), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

2.2.2 With TCC (no interaction)

dataInput=dataTrial_KS

dataInput = dataInput %>% filter(sol==1)

logitRandomIntercept = brm2(correct ~ nSolutions + phaseT +  (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0,
                           save_all_pars = TRUE)

tableName='ks_acc_ns2'
save_summarise_model(allModels[['ks_acc_ns2']], tableName)
Model Name already exists!

Marginal Effects

#marginal_effects(logitRandomIntercept, ask=FALSE)
plot(marginal_effects(allModels[['ks_acc_ns2']]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

2.2.3 Alone

dataInput=dataTrial_KS

dataInput = dataInput %>% filter(sol==1)

logitRandomIntercept = brm2(correct ~ nSolutions +  (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0,
                           save_all_pars = TRUE)

# m3 = logitRandomIntercept
tableName='ks_acc_ns3'
save_summarise_model(allModels[['ks_acc_ns3']], tableName)
Model Name already exists!

2.2.3.1 Plot

dataInput=dataTrial_KS

dataInput = dataInput %>% filter(sol==1)

model_ICexpost = allModels[['ks_acc_ns3']]

mean_accuracy = dataInput %>% group_by(id,phaseT,sol,nSolutions,ICexpost) %>% 
  summarise(accuracy = mean(correct))
`summarise()` regrouping output by 'id', 'phaseT', 'sol', 'nSolutions' (override with `.groups` argument)
pp  = plot(conditional_effects(model_ICexpost), plot = TRUE, ask = FALSE)


pp$nSolutions + 
  geom_point(data=mean_accuracy,aes(x = nSolutions, y = accuracy, col=as.factor(phaseT)),inherit.aes = FALSE)+
  theme_minimal()

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_accuracy,
                               aes(x = nSolutions, y = accuracy, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Number of solution witnesses")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+# c( "#FC4E07","#E7B800"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  scale_x_continuous(breaks = c(1,5,9,13))+
  ylim(0.2,1)

plo
ggsave(paste0(folderOut_figures,"/Nwit_KS_acc.pdf"),plo,width = 6,height =6,units="in")

2.3 ICexpost

2.3.1 All instances

dataInput = dataTrial_KS
model_ICexpost = brm2(correct ~ ICexpost + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='ks_acc_icexpost1'
save_summarise_model(allModels[['ks_acc_icexpost1']], tableName)
Model Name already exists!

2.3.1.0.1 Model Fit
#st05
dataInput = dataTrial_KS

model_ICexpost = allModels[['ks_acc_icexpost1']]

# Make predictions excluding random effects (pID)
predictions = predict(model_ICexpost, dataInput, re_formula = NA)

# Estimating the significance of the fit. This is done considering the probability estimation rather than the binary classification.

#Performs the Hosmer-Lemeshow goodness of fit test
logistic_significance = generalhoslem::logitgof(dataInput$correct, 
                                                predictions[,1], g = 10, ord = FALSE)
logistic_significance

    Hosmer and Lemeshow test (binary model)

data:  dataInput$correct, predictions[, 1]
X-squared = 60.184, df = 8, p-value = 4.288e-10
# Finds R2 using binary outcomes
# https://stackoverflow.com/questions/40901445/function-to-calculate-r2-r-squared-in-r
#predictions = predict(model_ICexpost,dataInput, re_formula = NA)
r_2_binary = cor(dataInput$correct, predictions[,1])^2
r_2_binary
[1] 0.1171649
# Finds R2 using mean accuracies per instance
predictions2 = predict(model_ICexpost,mean_accuracy, re_formula = NA)
r_2_probabilities = cor(mean_accuracy$accuracy, predictions2[,1])^2
r_2_probabilities
[1] 0.466316

2.3.1.1 Plot

dataInput = dataTrial_KS
model_ICexpost = allModels[['ks_acc_icexpost1']]

mean_accuracy = dataInput %>% group_by(instanceNumber,phaseT,sol,ICexpost) %>% 
  summarise(accuracy = mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'phaseT', 'sol' (override with `.groups` argument)
pp  = plot(conditional_effects(model_ICexpost), plot = TRUE, ask = FALSE)


pp$ICexpost + 
  geom_point(data=mean_accuracy,aes(x = ICexpost, y = accuracy, col=as.factor(phaseT)),inherit.aes = FALSE)+
  theme_minimal()

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_accuracy,
                               aes(x = ICexpost, y = accuracy, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
# geom_point(data=mean_accuracy,aes(x = ICexpost, y = correct, col=as.factor(sol),shape=as.factor(phaseT), size=2.5),inherit.aes = FALSE)+
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+# c( "#FC4E07","#E7B800"))+
  # scale_shape_manual(name="IC",values = c(2, 8))+
  # scale_color_manual(name="Solution",values = c("red", "blue"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)

plo
ggsave(paste0(folderOut_figures,"/IC_KS_acc.pdf"),plo,width = 6,height =6,units="in")

2.3.2 Unsatisfiable instances

dataInput = dataTrial_KS
dataInput = dataInput %>% filter(sol==0)
model_ICexpost = brm2(correct ~ ICexpost + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='ks_acc_icexpost2'
save_summarise_model(allModels[['ks_acc_icexpost2']], tableName)
Model Name already exists!

2.4 Plot TCC


dataInput = dataTrial_KS
dataInput = dataInput %>% 
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained"))

dataInput2 = dataInput %>% group_by(instanceNumber,region) %>%
  summarise(accuracy=mean(correct))
`summarise()` regrouping output by 'instanceNumber' (override with `.groups` argument)
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

plo = ggplot(dataInput2,aes(x=region,y=accuracy,fill=region))+
  geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("Underconstrained", "Phase Transition", "Overconstrained"),
                    labels=c("Underconstrained", "Phase Transition", "Overconstrained"),
                    values=c(rgb(249,199,79, max=255),
                             rgb(205,54,56, max=255),
                             rgb(249,199,79, max=255)))+
  geom_signif(annotations = c("***","***"),
             y_position=c(1.05,1.05),xmin=c(1.05,2.1),xmax=c(1.9,2.95))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Human Performance")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))


plo
ggsave(paste0(folderOut_figures,"/TCC_KS_acc.pdf"),plo,width = 6,height =6,units="in")

#brewer
dataInput = dataTrial_KS
dataInput = dataInput %>%
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained"))%>%
  mutate(sol= as.factor(sol)) %>%
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput2 = dataInput %>%
  group_by(instanceNumber,region,sol) %>%
  summarise(accuracy=mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'region' (override with `.groups` argument)

plo = ggplot(dataInput2,aes(x=region,y=accuracy,fill=sol))+
  # geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape= NA)+
                 #,outlier.shape = 4, outlier.size=0.9)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Human Performance")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)

plo
ggsave(paste0(folderOut_figures,"/TCC_KS_acc1.pdf"),plo,width = 7,height =6,units="in")

3 Save Models

# saveRDS(allModels,file.path(folderOut,"ICx3_models_KS.RData"))
LS0tCnRpdGxlOiAiQmVoYXZpb3VyYWwgcmVzdWx0cyBmb3IgdGhlIGtuYXBzYWNrIHRhc2siCmF1dGhvcjogIkouIFBhYmxvIEZyYW5jbyIKZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IHVuaXRlZAogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCi0tLQoKYGBge3IgZG9jX3NldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKYGBgez1odG1sfQo8c3R5bGU+Cgp0YWJsZSwgdGQsIHRoIHsKICBib3JkZXI6IG5vbmU7CiAgcGFkZGluZy1sZWZ0OiAxZW07CiAgcGFkZGluZy1yaWdodDogMWVtOwogIG1pbi13aWR0aDogNTAlOwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKICBtYXJnaW4tdG9wOiAxZW07CiAgbWFyZ2luLWJvdHRvbTogMWVtOwp9Cgo8L3N0eWxlPgpgYGAKCmBgYHtyIGZvbGRlcl9tYW5hZ2VtZW50fQoKcHJvamVjdF9mb2xkZXIgPSAiL1ZvbHVtZXMvR29vZ2xlRHJpdmUvTXkgRHJpdmUvTWVsYm91cm5lL1VOSU1FTEIvUmVzZWFyY2gvQ29tcGxleGl0eSBQcm9qZWN0L0lDeDNfbmV3L0NvZGUvYmVoYXZBbmFseXNpcy9JQ3gzX3N1cHAvIgpjb2RlX2ZvbGRlciA9IHBhc3RlMChwcm9qZWN0X2ZvbGRlciwgIkNvZGUvIikKZGF0YV9mb2xkZXIgPSBwYXN0ZTAocHJvamVjdF9mb2xkZXIsICJEYXRhLyIpCgpzZXR3ZChjb2RlX2ZvbGRlcikKa25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBjb2RlX2ZvbGRlcikKCiNJbXBvcnQgZnVuY3Rpb25zCnNvdXJjZShmaWxlLnBhdGgoY29kZV9mb2xkZXIsIkRlc2NyaXB0aXZlRnVuY3Rpb25zLlIiKSkKCiMgUGFydGljaXBhbnQgRGF0YQpmb2xkZXJNb2RlbHMgPSAiL1ZvbHVtZXMvR29vZ2xlRHJpdmUvTXkgRHJpdmUvTWVsYm91cm5lL1VOSU1FTEIvUmVzZWFyY2gvQ29tcGxleGl0eSBQcm9qZWN0L0lDeDNfbmV3L0NvZGUvYmVoYXZBbmFseXNpcy9PdXRwdXQvIgoKZm9sZGVyT3V0X2ZpZ3VyZXMgPSBwYXN0ZTAocHJvamVjdF9mb2xkZXIsIk91dHB1dC9GaWd1cmVzIikKZm9sZGVyT3V0X3RhYmxlcyA9IHBhc3RlMChwcm9qZWN0X2ZvbGRlciwiT3V0cHV0L1RhYmxlcyIpCmBgYAoKYGBge3Igc2V0dXAsIGNvbGxhcHNlPVRSVUV9CiMjIFNldHRpbmcgdXAgdGhlIGJhc2ljcwpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dzaWduaWYpCmxpYnJhcnkocGFuZGVyKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShyZXNoYXBlMikKbGlicmFyeShIbWlzYykKbGlicmFyeShyZWFkcikKbGlicmFyeShicm1zKQpsaWJyYXJ5KHBhcmFsbGVsKQpsaWJyYXJ5KHNqc3RhdHMpCmxpYnJhcnkoYmF5ZXNwbG90KQpsaWJyYXJ5KGJtbG0pCmxpYnJhcnkoRGlhZ3JhbW1lUikKbGlicmFyeSh0aWR5cikKCiNGcm9tIGVhc3lzdGF0czoKbGlicmFyeShwYXJhbWV0ZXJzKQpsaWJyYXJ5KHNlZSkKbGlicmFyeShiYXllc3Rlc3RSKQpsaWJyYXJ5KHBlcmZvcm1hbmNlKQpsaWJyYXJ5KGZvcmNhdHMpCmxpYnJhcnkoZ2dwb2wpCgpgYGAKCmBgYHtyfQojIGJybXMgSW5wdXQKCmNoYWluc19icm1zID0gNApjb3Jlc19icm1zID0gbWluKGNoYWluc19icm1zLGRldGVjdENvcmVzKCkpCnNlZWRfYnJtcyA9IDExMQppdGVyc19oaWdoID0gNDAwMAoKYGBgCgpgYGB7cn0KIyBGdW5jdGlvbnMKc2F2ZV9zdW1tYXJpc2VfbW9kZWwgPSBmdW5jdGlvbihtb2RlbCwgbW9kZWxOYW1lKXsKICBpZiAobW9kZWxOYW1lICVpbiUgbmFtZXMoYWxsTW9kZWxzKSl7CiAgICB3YXJuaW5nKCJNb2RlbCBOYW1lIGFscmVhZHkgZXhpc3RzISIpCiAgICBtb2RlbCA9IGFsbE1vZGVsc1tbbW9kZWxOYW1lXV0KICB9IGVsc2UgewogICAgYWxsTW9kZWxzW1ttb2RlbE5hbWVdXTw8LSBtb2RlbAogIH0KIAogICAgdGFibGUgPSBtb2RlbF9wYXJhbWV0ZXJzKG1vZGVsLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2lfbWV0aG9kID0gIkhESSIsY2k9MC45NSx0ZXN0ID0gYygiaGRpIiwicGQiKSkKICAgIAogICAgdGFibGUyID0gcGVyZm9ybWFuY2U6Om1vZGVsX3BlcmZvcm1hbmNlKG1vZGVsLG1ldHJpY3M9ImNvbW1vbiIpCgogICAgcGxvID0gcGxvdChoZGkobW9kZWwsIGNpID0gYygwLjk1KSksIGRhdGEgPSBtb2RlbCkrCiAgICAgICAgICBnZ3RpdGxlKCJQb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyIsCiAgICAgICAgICAgICAgICAgICJ3aXRoIG1lZGlhbnMgYW5kIDk1JSBxdWFudGlsZS1iYXNlZC1pbnRlcnZhbHMiKSArCiAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQogIAogICAgcHJpbnQoYXNfdGliYmxlKHRhYmxlKSkKICAgIHByaW50KGFzX3RpYmJsZSh0YWJsZTIpKQogICAgcHJpbnQocGxvKQogICAgCiAgICBhbGxNb2RlbHNbW21vZGVsTmFtZV1dPDwtIG1vZGVsCn0KCmBgYAoKYGBge3J9CiMgVXNlIGN1cnJlbnQgbW9kZWxzIG9yIHJlcnVuIGV2ZXJ5dGhpbmcgQ29tbWVudCBvbmUgb3B0aW9uCgojIGFsbE1vZGVscyA6PSBsaXN0IG9mIGFsbCB0aGUgcmVncmVzc2lvbnMgdGhhdCBhcmUgcnVuIAoKCiMjIE9wdGlvbjE6IFVzZSBjdXJyZW50IHNhdmVkIG1vZGVscwoKIyBJbXBvcnQgZXN0aW1hdGVkIG1vZGVscwphbGxNb2RlbHMgPSByZWFkX3JkcyhmaWxlLnBhdGgoZm9sZGVyTW9kZWxzLCJJQ3gzX21vZGVsc19LUy5SRGF0YSIpKQoKIyBEb24ndCBydW4gYnJtcyBtb2RlbHMKYnJtMiA9ICBmdW5jdGlvbiguLi4pewogIHJldHVybihGQUxTRSkKfQoKIyAjIyBPcHRpb24yOiBSZXJ1biBldmVyeXRoaW5nIGZyb20gc2NyYXRjaAojIAojIGFsbE1vZGVscz12ZWN0b3IoImxpc3QiLCBsZW5ndGg9MCkKIyAKIyBicm0yID0gIGZ1bmN0aW9uKC4uLil7CiMgICByZXR1cm4oYnJtKC4uLikpCiMgfQoKCmBgYAoKIyBLbmFwc2FjayBkZWNpc2lvbiBwcm9ibGVtIChLUCkKCiMgQWNjdXJhY3kgCgpSZWFkIENsZWFuIERhdGEgdG8gZmlsZQoKYGBge3J9CgpkYXRhVHJpYWxfS1M9IHJlYWRfY3N2KGZpbGUucGF0aChkYXRhX2ZvbGRlciwiS1NEZWNfY2xlYW4uY3N2IiksCiAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyh3ID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdiA9IGNvbF9jaGFyYWN0ZXIoKSkpCgoKZGF0YVRyaWFsX0tTJHJlZ2lvbiA9IGNhc2Vfd2hlbigKICBkYXRhVHJpYWxfS1MkdHlwZSAlaW4lIGMoMSwyLDMsNCkgfiAiUGhhc2UgVHJhbnNpdGlvbiIsCiAgZGF0YVRyaWFsX0tTJHR5cGUgJWluJSBjKDYpIH4gIlVuZGVyY29uc3RyYWluZWQiLAogIGRhdGFUcmlhbF9LUyR0eXBlICVpbiUgYyg1KSB+ICJPdmVyY29uc3RyYWluZWQiCikKCmBgYAoKIyMgU2F0aXNmaWFiaWxpdHkKCmBgYHtyfQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX0tTCgpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IHNvbCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhdmVfYWxsX3BhcnMgPSBUUlVFKQoKdGFibGVOYW1lPSdrc19hY2Nfc2F0MScKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgojIyBOdW1iZXIgb2Ygd2l0bmVzc2VzIAoKIyMjIFdpdGggVENDCgpgYGB7cn0KZGF0YUlucHV0PWRhdGFUcmlhbF9LUwoKZGF0YUlucHV0ID0gZGF0YUlucHV0ICU+JSBmaWx0ZXIoc29sPT0xKQoKZGF0YUlucHV0JG5Tb2x1dGlvbnNfbG9nID1sb2coZGF0YUlucHV0JG5Tb2x1dGlvbnMpCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gblNvbHV0aW9ucyArIHBoYXNlVCArIHBoYXNlVDpuU29sdXRpb25zICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZV9hbGxfcGFycyA9IFRSVUUpCgp0YWJsZU5hbWU9J2tzX2FjY19uczEnCnNhdmVfc3VtbWFyaXNlX21vZGVsKGFsbE1vZGVsc1tbJ2tzX2FjY19uczEnXV0sIHRhYmxlTmFtZSkKYGBgCgpgYGB7cn0KbW9kZWwgPSBhbGxNb2RlbHNbWydrc19hY2NfbnMxJ11dCnBsb3QobWFyZ2luYWxfZWZmZWN0cyhtb2RlbCksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKYGBgCgojIyMgV2l0aCBUQ0MgKG5vIGludGVyYWN0aW9uKQoKYGBge3J9CmRhdGFJbnB1dD1kYXRhVHJpYWxfS1MKCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gblNvbHV0aW9ucyArIHBoYXNlVCArICAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHk9YmVybm91bGxpKGxpbms9ImxvZ2l0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2ggPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzYXZlX2FsbF9wYXJzID0gVFJVRSkKCnRhYmxlTmFtZT0na3NfYWNjX25zMicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwoYWxsTW9kZWxzW1sna3NfYWNjX25zMiddXSwgdGFibGVOYW1lKQpgYGAKCk1hcmdpbmFsIEVmZmVjdHMKCmBgYHtyfQojbWFyZ2luYWxfZWZmZWN0cyhsb2dpdFJhbmRvbUludGVyY2VwdCwgYXNrPUZBTFNFKQpwbG90KG1hcmdpbmFsX2VmZmVjdHMoYWxsTW9kZWxzW1sna3NfYWNjX25zMiddXSksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKYGBgCgojIyMgQWxvbmUKCmBgYHtyfQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX0tTCgpkYXRhSW5wdXQgPSBkYXRhSW5wdXQgJT4lIGZpbHRlcihzb2w9PTEpCgpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IG5Tb2x1dGlvbnMgKyAgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZV9hbGxfcGFycyA9IFRSVUUpCgojIG0zID0gbG9naXRSYW5kb21JbnRlcmNlcHQKdGFibGVOYW1lPSdrc19hY2NfbnMzJwpzYXZlX3N1bW1hcmlzZV9tb2RlbChhbGxNb2RlbHNbWydrc19hY2NfbnMzJ11dLCB0YWJsZU5hbWUpCgpgYGAKCiMjIyMgUGxvdAoKYGBge3J9CmRhdGFJbnB1dD1kYXRhVHJpYWxfS1MKCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKCm1vZGVsX0lDZXhwb3N0ID0gYWxsTW9kZWxzW1sna3NfYWNjX25zMyddXQoKbWVhbl9hY2N1cmFjeSA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkoaWQscGhhc2VULHNvbCxuU29sdXRpb25zLElDZXhwb3N0KSAlPiUgCiAgc3VtbWFyaXNlKGFjY3VyYWN5ID0gbWVhbihjb3JyZWN0KSkKCnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhtb2RlbF9JQ2V4cG9zdCksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKCnBwJG5Tb2x1dGlvbnMgKyAKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeSxhZXMoeCA9IG5Tb2x1dGlvbnMsIHkgPSBhY2N1cmFjeSwgY29sPWFzLmZhY3RvcihwaGFzZVQpKSxpbmhlcml0LmFlcyA9IEZBTFNFKSsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpgYGB7cn0KIyBJbXByb3ZpbmcgdGhlIHBsb3QKc2l6ZV9iaWcgPSAyMApzaXplX3NtYWxsID0gMTYKc2l6ZV9zcyA9IDEwCnNpemVfeHMgPSA3CgpwcF9wbG90ID0gcHAkblNvbHV0aW9ucwpwcF9wbG90JGxheWVyc1tbMV1dJGdlb21fcGFyYW1zJHNlID0gRkFMU0UKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjdXJhY3ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IG5Tb2x1dGlvbnMsIHkgPSBhY2N1cmFjeSwgY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksIGluaGVyaXQuYWVzID0gRkFMU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHBfcGxvdCRsYXllcnMpCgoKcGxvID0gcHBfcGxvdCArCiAgeGxhYigiTnVtYmVyIG9mIHNvbHV0aW9uIHdpdG5lc3NlcyIpKyNleHByZXNzaW9uKElDW2V4cG9zdF0pKSsKICB5bGFiKCJIdW1hbiBQZXJmb3JtYW5jZSIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsjIGMoICIjRkM0RTA3IiwiI0U3QjgwMCIpKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPSBzaXplX2JpZyksCiAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9c2l6ZV9zbWFsbCksCiAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDEsNSw5LDEzKSkrCiAgeWxpbSgwLjIsMSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvTndpdF9LU19hY2MucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgojIyBJQ2V4cG9zdAoKIyMjIEFsbCBpbnN0YW5jZXMKCmBgYHtyfQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfS1MKbW9kZWxfSUNleHBvc3QgPSBicm0yKGNvcnJlY3QgfiBJQ2V4cG9zdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J2tzX2FjY19pY2V4cG9zdDEnCnNhdmVfc3VtbWFyaXNlX21vZGVsKGFsbE1vZGVsc1tbJ2tzX2FjY19pY2V4cG9zdDEnXV0sIHRhYmxlTmFtZSkKCmBgYAoKIyMjIyMgTW9kZWwgRml0CgpgYGB7cn0KI3N0MDUKZGF0YUlucHV0ID0gZGF0YVRyaWFsX0tTCgptb2RlbF9JQ2V4cG9zdCA9IGFsbE1vZGVsc1tbJ2tzX2FjY19pY2V4cG9zdDEnXV0KCiMgTWFrZSBwcmVkaWN0aW9ucyBleGNsdWRpbmcgcmFuZG9tIGVmZmVjdHMgKHBJRCkKcHJlZGljdGlvbnMgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LCBkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKCiMgRXN0aW1hdGluZyB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBmaXQuIFRoaXMgaXMgZG9uZSBjb25zaWRlcmluZyB0aGUgcHJvYmFiaWxpdHkgZXN0aW1hdGlvbiByYXRoZXIgdGhhbiB0aGUgYmluYXJ5IGNsYXNzaWZpY2F0aW9uLgoKI1BlcmZvcm1zIHRoZSBIb3NtZXItTGVtZXNob3cgZ29vZG5lc3Mgb2YgZml0IHRlc3QKbG9naXN0aWNfc2lnbmlmaWNhbmNlID0gZ2VuZXJhbGhvc2xlbTo6bG9naXRnb2YoZGF0YUlucHV0JGNvcnJlY3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVkaWN0aW9uc1ssMV0sIGcgPSAxMCwgb3JkID0gRkFMU0UpCmxvZ2lzdGljX3NpZ25pZmljYW5jZQoKIyBGaW5kcyBSMiB1c2luZyBiaW5hcnkgb3V0Y29tZXMKIyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MDkwMTQ0NS9mdW5jdGlvbi10by1jYWxjdWxhdGUtcjItci1zcXVhcmVkLWluLXIKI3ByZWRpY3Rpb25zID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKcl8yX2JpbmFyeSA9IGNvcihkYXRhSW5wdXQkY29ycmVjdCwgcHJlZGljdGlvbnNbLDFdKV4yCnJfMl9iaW5hcnkKCiMgRmluZHMgUjIgdXNpbmcgbWVhbiBhY2N1cmFjaWVzIHBlciBpbnN0YW5jZQpwcmVkaWN0aW9uczIgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LG1lYW5fYWNjdXJhY3ksIHJlX2Zvcm11bGEgPSBOQSkKcl8yX3Byb2JhYmlsaXRpZXMgPSBjb3IobWVhbl9hY2N1cmFjeSRhY2N1cmFjeSwgcHJlZGljdGlvbnMyWywxXSleMgpyXzJfcHJvYmFiaWxpdGllcwpgYGAKCiMjIyMgUGxvdAoKYGBge3J9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9LUwptb2RlbF9JQ2V4cG9zdCA9IGFsbE1vZGVsc1tbJ2tzX2FjY19pY2V4cG9zdDEnXV0KCm1lYW5fYWNjdXJhY3kgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLHBoYXNlVCxzb2wsSUNleHBvc3QpICU+JSAKICBzdW1tYXJpc2UoYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QpKQoKcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKG1vZGVsX0lDZXhwb3N0KSwgcGxvdCA9IFRSVUUsIGFzayA9IEZBTFNFKQoKcHAkSUNleHBvc3QgKyAKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeSxhZXMoeCA9IElDZXhwb3N0LCB5ID0gYWNjdXJhY3ksIGNvbD1hcy5mYWN0b3IocGhhc2VUKSksaW5oZXJpdC5hZXMgPSBGQUxTRSkrCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcHBfcGxvdCA9IHBwJElDZXhwb3N0CnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gSUNleHBvc3QsIHkgPSBhY2N1cmFjeSwgY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksIGluaGVyaXQuYWVzID0gRkFMU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHBfcGxvdCRsYXllcnMpCgoKcGxvID0gcHBfcGxvdCArCiMgZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjdXJhY3ksYWVzKHggPSBJQ2V4cG9zdCwgeSA9IGNvcnJlY3QsIGNvbD1hcy5mYWN0b3Ioc29sKSxzaGFwZT1hcy5mYWN0b3IocGhhc2VUKSwgc2l6ZT0yLjUpLGluaGVyaXQuYWVzID0gRkFMU0UpKwogIHhsYWIoIkluc3RhbmNlIENvbXBsZXhpdHkgKElDKSIpKyNleHByZXNzaW9uKElDW2V4cG9zdF0pKSsKICB5bGFiKCJIdW1hbiBQZXJmb3JtYW5jZSIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsjIGMoICIjRkM0RTA3IiwiI0U3QjgwMCIpKSsKICAjIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSJJQyIsdmFsdWVzID0gYygyLCA4KSkrCiAgIyBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iU29sdXRpb24iLHZhbHVlcyA9IGMoInJlZCIsICJibHVlIikpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgwLjIsMSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvSUNfS1NfYWNjLnBkZiIpLHBsbyx3aWR0aCA9IDYsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCmBgYAoKIyMjIFVuc2F0aXNmaWFibGUgaW5zdGFuY2VzCgpgYGB7cn0KZGF0YUlucHV0ID0gZGF0YVRyaWFsX0tTCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MCkKbW9kZWxfSUNleHBvc3QgPSBicm0yKGNvcnJlY3QgfiBJQ2V4cG9zdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J2tzX2FjY19pY2V4cG9zdDInCnNhdmVfc3VtbWFyaXNlX21vZGVsKGFsbE1vZGVsc1tbJ2tzX2FjY19pY2V4cG9zdDInXV0sIHRhYmxlTmFtZSkKCmBgYAoKIyMgUGxvdCBUQ0MKCmBgYHtyfQoKZGF0YUlucHV0ID0gZGF0YVRyaWFsX0tTCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgCiAgbXV0YXRlKHJlZ2lvbiA9IGZjdF9yZWxldmVsKHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZGVyY29uc3RyYWluZWQiLCAiUGhhc2UgVHJhbnNpdGlvbiIsICJPdmVyY29uc3RyYWluZWQiKSkKCmRhdGFJbnB1dDIgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLHJlZ2lvbikgJT4lCiAgc3VtbWFyaXNlKGFjY3VyYWN5PW1lYW4oY29ycmVjdCkpCgpgYGAKCmBgYHtyfQpzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBsbyA9IGdncGxvdChkYXRhSW5wdXQyLGFlcyh4PXJlZ2lvbix5PWFjY3VyYWN5LGZpbGw9cmVnaW9uKSkrCiAgZ2VvbV9ib3hqaXR0ZXIoYWVzKGZpbGw9cmVnaW9uKSxqaXR0ZXIuY29sb3IgPSBOQSxqaXR0ZXIuc2hhcGUgPSAyMSkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSAgPSJSZWdpb24iLAogICAgICAgICAgICAgICAgICAgIGJyZWFrcz1jKCJVbmRlcmNvbnN0cmFpbmVkIiwgIlBoYXNlIFRyYW5zaXRpb24iLCAiT3ZlcmNvbnN0cmFpbmVkIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIlVuZGVyY29uc3RyYWluZWQiLCAiUGhhc2UgVHJhbnNpdGlvbiIsICJPdmVyY29uc3RyYWluZWQiKSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9YyhyZ2IoMjQ5LDE5OSw3OSwgbWF4PTI1NSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmdiKDIwNSw1NCw1NiwgbWF4PTI1NSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmdiKDI0OSwxOTksNzksIG1heD0yNTUpKSkrCiAgZ2VvbV9zaWduaWYoYW5ub3RhdGlvbnMgPSBjKCIqKioiLCIqKioiKSwKICAgICAgICAgICAgIHlfcG9zaXRpb249YygxLjA1LDEuMDUpLHhtaW49YygxLjA1LDIuMSkseG1heD1jKDEuOSwyLjk1KSkrCiAgeGxhYigiVHlwaWNhbCBDYXNlIENvbXBsZXhpdHkgKFRDQykiKSsKICB5bGFiKCJIdW1hbiBQZXJmb3JtYW5jZSIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkKCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL1RDQ19LU19hY2MucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKI2JyZXdlcgpgYGAKCmBgYHtyfQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfS1MKZGF0YUlucHV0ID0gZGF0YUlucHV0ICU+JQogIG11dGF0ZShyZWdpb24gPSBmY3RfcmVsZXZlbChyZWdpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmRlcmNvbnN0cmFpbmVkIiwgIlBoYXNlIFRyYW5zaXRpb24iLCAiT3ZlcmNvbnN0cmFpbmVkIikpJT4lCiAgbXV0YXRlKHNvbD0gYXMuZmFjdG9yKHNvbCkpICU+JQogIG11dGF0ZShzb2wgPSBmY3RfcmVsZXZlbChzb2wsIjEiLCAiMCIpKQoKZGF0YUlucHV0MiA9IGRhdGFJbnB1dCAlPiUKICBncm91cF9ieShpbnN0YW5jZU51bWJlcixyZWdpb24sc29sKSAlPiUKICBzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihjb3JyZWN0KSkKYGBgCgpgYGB7cn0KCnBsbyA9IGdncGxvdChkYXRhSW5wdXQyLGFlcyh4PXJlZ2lvbix5PWFjY3VyYWN5LGZpbGw9c29sKSkrCiAgIyBnZW9tX2JveGppdHRlcihhZXMoZmlsbD1yZWdpb24pLGppdHRlci5jb2xvciA9IE5BLGppdHRlci5zaGFwZSA9IDIxKSsKICBnZW9tX2JveGppdHRlcihqaXR0ZXIuY29sb3IgPSBOQSxqaXR0ZXIuc2hhcGUgPSAyMSwKICAgICAgICAgICAgICAgICBqaXR0ZXIucGFyYW1zID0gbGlzdChoZWlnaHQ9MCxzZWVkPTEwKSwKICAgICAgICAgICAgICAgICBvdXRsaWVyLnNoYXBlPSBOQSkrCiAgICAgICAgICAgICAgICAgIyxvdXRsaWVyLnNoYXBlID0gNCwgb3V0bGllci5zaXplPTAuOSkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSAgPSJSZWdpb24iLAogICAgICAgICAgICAgICAgICAgIGJyZWFrcz1jKCIxIiwiMCIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJTYXRpc2ZpYWJsZSIsIlVuc2F0aXNmaWFibGUiKSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9YygiIzkwQkU2RCIsIiNGOTQxNDQiKSkrCiAgeGxhYigiVHlwaWNhbCBDYXNlIENvbXBsZXhpdHkgKFRDQykiKSsKICB5bGFiKCJIdW1hbiBQZXJmb3JtYW5jZSIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgwLjIsMSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvVENDX0tTX2FjYzEucGRmIikscGxvLHdpZHRoID0gNyxoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgojIFNhdmUgTW9kZWxzCgpgYGB7cn0KIyBzYXZlUkRTKGFsbE1vZGVscyxmaWxlLnBhdGgoZm9sZGVyT3V0LCJJQ3gzX21vZGVsc19LUy5SRGF0YSIpKQpgYGAKCg==